<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
	<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
	<meta http-equiv="Content-language" content="en" /> 
	<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> 
	<meta name="description" content="RestFB is a simple but powerful Facebook REST API client written in Java" />
	<link rel="canonical" href="http://restfb.com" /> 
	<title>RestFB - A Lightweight Java Facebook REST API Client</title> 	
	<link type="text/css" rel="stylesheet" href="style.css" />	
	<script type="text/javascript" src="jquery.js"></script>	
	<script type="text/javascript" src="prettify.js"></script>
	<script type="text/javascript">
	$(function() {
		prettyPrint();
		
		$("#json-display-link").click(function() {
			$("#json-display").toggle();			
			var text = $(this).text();
			$(this).text($("#json-display").is(":visible")
				? text.replace("see", "hide")
				: text.replace("hide", "see"));								
			return false;
		});
	});
	</script>		
</head>
<body>
	<div id="content">
		<div class="spacer"></div>
	
		<h1>Using RestFB with Facebook's Old REST API</h1>
		
		<p>
			As always, you can jump straight to the <a href="javadoc/index.html">RestFB Javadoc</a>, or learn by example below.
		</p>
		
		<p>
			If you're looking for help or additional examples, please check out the <a href="http://groups.google.com/group/restfb">RestFB Google Group</a>.
		</p>		
		
		<div class="spacer"></div>		
		
		<div class="warning-bubble">
			<h3>The below documentation is for the Old REST API component of RestFB.</h3>
						
			<div>
				Keep in mind that it's preferable for new projects to use the default Facebook Graph API component of RestFB, which is <a href="index.html">documented here</a>.
				Facebook will be deprecating the Old REST API in the future, and most active development work on both Facebook and RestFB will center around the Graph API.				
			</div>
			
			<div class="spacer"></div>
			
			<div>
				It's worth noting that there are still two good reasons to use the Old REST API: Legacy code that depends on it, and functionality gaps in the Graph API.
			</div>			
		</div>		
		
		<div class="spacer"></div>
		
		<h3>Initialization</h3>
		
		<pre class="prettyprint">
// <a href="javadoc/com/restfb/DefaultLegacyFacebookClient.html">DefaultLegacyFacebookClient</a> is the <a href="javadoc/com/restfb/LegacyFacebookClient.html">LegacyFacebookClient</a> implementation
// that ships with RestFB. You can customize it by passing in
// custom <a href="javadoc/com/restfb/JsonMapper.html">JsonMapper</a> and <a href="javadoc/com/restfb/WebRequestor.html">WebRequestor</a> implementations, or simply
// write your own FacebookClient instead for maximum control

// Use this constructor if you'd like to go with legacy authentication (not recommended) 
LegacyFacebookClient facebookClient = new DefaultLegacyFacebookClient(MY_API_KEY, MY_SECRET_KEY);

// Use this constructor if you'd like to go with the new OAuth token authentication (preferred)
LegacyFacebookClient facebookClient = new DefaultLegacyFacebookClient(MY_ACCESS_TOKEN);</pre>		
		
		<div class="spacer"></div>
		
		<div class="warning-bubble">
			<h3>Not sure how to get an OAuth access token?</h3>
						
			<div>
				It's really easy with the Facebook Graph API.  Sign in to Facebook and <a href="http://developers.facebook.com/docs/api">navigate to the Graph API documentation</a>.
				Click on one of the example links that shows Graph API JSON data.
			</div>	
			
			<div class="spacer"></div>
			
			<div>
				You should see an <code>access_token</code> parameter in your URL bar.  That's it!  Just copy and paste it into your code.								
			</div>
			
			<div class="spacer"></div>
			
			<div>
				Example: <code>http://graph.facebook.com/btaylor?access_token=XXXXXXX</code>
			</div>
		</div>			
		
		<div class="spacer"></div>
		
		<h3>Making a Simple Call</h3>
		
		<p>
			We'll get the <code>UID</code> associated with the current Facebook API session key by calling the API method <code><a href="http://wiki.developers.facebook.com/index.php/Users.getLoggedInUser">users.getLoggedInUser</a></code>.
		</p>	
		
		<pre class="prettyprint">
// Last parameter specifies that this API call's result
// should be returned to us as a Long value

Long uid = facebookClient.<a href="javadoc/com/restfb/LegacyFacebookClient.html#execute(java.lang.String,%20java.lang.Class,%20com.restfb.Parameter...)">execute</a>("users.getLoggedInUser", Long.class);</pre>

		<div class="spacer"></div>
		
		<div class="warning-bubble">
			<h3>Before we go further, a few words about logging...</h3>
						
			<div>
				RestFB uses java.util.logging to emit information about the data that's sent over the wire to and from Facebook.
				It's often very helpful to look at the logs so you can make sure that RestFB is sending the data as you expect it to
				and that Facebook is returning the correct JSON.
			</div>	
			
			<div class="spacer"></div>
			
			<div>
				Want to use <a target="_blank" href="http://logging.apache.org/log4j/1.2/">Log4j</a> instead of java.util.logging?  
				No problem!  Just download the latest release of <a target="_blank" href="http://www.slf4j.org/">slf4j</a> and drop these two JARs onto your classpath and everything should just work:
				
				<div class="spacer"></div>
								
				<ul>
					<li>slf4j-api-x.y.jar</li>
					<li>slf4j-log4j12-x.y.jar</li>
				</ul>							
			</div>			
		</div>			
		
		<div class="spacer"></div>		
			
		<h3>Making a More Complex Call</h3>
		
		<p>
			Here we make the API call <code>fql.query</code> to execute a custom query.		
		</p>
		
		<pre class="prettyprint">
// FQL query which asks Facebook for your friends' names,
// profile picture URLs, and network affiliations

String query =
  "SELECT name, pic_big, affiliations FROM user " +
  "WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=12345)";

// Executes an API call with result mapped to a list of classes we've defined.
// Note that you can pass in an arbitrary number of <a href="javadoc/com/restfb/Parameter.html">Parameter</a>s - here we
// send along the query as well as the "give me HTTPS URLs" flag

List&lt;User&gt; users =
  facebookClient.<a href="javadoc/com/restfb/LegacyFacebookClient.html#executeForList(java.lang.String,%20java.lang.Class,%20com.restfb.Parameter...)">executeForList</a>("fql.query", User.class,
    Parameter.with("query", query), Parameter.with("return_ssl_resources", "true"));</pre>	
		
		<h3>1. What Happened Under the Covers</h3>
		
		<p>
			The Facebook API returned JSON in response to our query.  You can <a id="json-display-link" href="javascript://">click here to see it</a>.		
		</p>
		
		<pre id="json-display" class="prettyprint" style="display: none;">
[
  {
    "affiliations":
      [
        {
          "nid":50431663,
          "name":"Intuit",
          "type":"work",
          "status":"",
          "year":0
        }
      ],
    "name":"Heather Merlino",
    "pic_big":"https:\/\/secure-profile.facebook.com\/profile6\/138\/106\/n28455_7662.jpg"
  },
  {
    "affiliations":
      [
        {
          "nid":16777221,
          "name":"Cornell",
          "type":"college",
          "status":"Alumnus\/Alumna",
          "year":2004
        },
        {
          "nid":50431762,
          "name":"Bain &amp; Company",
          "type":"work",
          "status":"",
          "year":0
        }
      ],
    "name":"Steve Nolan",
    "pic_big":"https:\/\/secure-profile.facebook.com\/v228\/344\/541\/n4057387_1795.jpg"
  },
  {
    "affiliations":{},
    "name":"Third Person",
    "pic_big":"https:\/\/secure-profile.facebook.com\/v2328\/314\/454\/n137387_5491.jpg"
  }
]</pre>		
		
		<h3>2. Turning JSON into Java</h3>
		
		<p>
			Since RestFB doesn't know in advance what kinds of data you're requesting from the API,
			you need to define your own JavaBean classes that map to API responses. Luckily, this is a simple
			process - just annotate fields with <code><a href="javadoc/com/restfb/Facebook.html">@Facebook</a></code> and RestFB will automatically convert
			Facebook's JSON to real Java objects.
		</p>	
	
		<pre class="prettyprint">
public class User {

  // By default, assumes JSON attribute name is the same as the Java field name  

  @Facebook
  String name;

  // If your Java field name is different than the JSON attribute name,
  // just specify the JSON attribute name
  
  @Facebook("pic_big")
  String pictureUrl;
  
  @Facebook
  List&lt;Affiliation&gt; affiliations;

  public String toString() {
    return String.format("Name: %s\nProfile Image URL: %s\nAffiliations: %s",
      name, pictureUrl, affiliations);
  }
}

public class Affiliation {
  @Facebook
  String name;

  @Facebook
  String type;

  public String toString() {
    return String.format("%s (%s)", name, type);
  }
}</pre>
	
		<h3>		
			3. Let's See the Results
		</h3>
		
		<pre class="prettyprint">
for (User user : users)
  System.out.println(user + "\n");</pre> 
		
		<p>	
			And here they are on stdout:
		</p>
		
		<pre>
Name: Heather Merlino
Profile Image URL: https://secure-profile.facebook.com/profile6/138/106/n28455_7662.jpg
Affiliations: [Intuit (work)]

Name: Steve Nolan
Profile Image URL: https://secure-profile.facebook.com/v228/344/541/n4057387_1795.jpg
Affiliations: [Cornell (college), Bain & Company (work)]

Name: Third Person
Profile Image URL: https://secure-profile.facebook.com/v2328/314/454/n137387_5491.jpg
Affiliations: []</pre>
		
		<div class="spacer"></div>				
		
		<h2>Making an fql.multiquery Call (Since 1.1)</h2>

		<p>
			Given the unique nature of the <a href="http://wiki.developers.facebook.com/index.php/Fql.multiquery">fql.multiquery</a> API call,
			RestFB provides the <a href="javadoc/com/restfb/LegacyFacebookClient.html#executeMultiquery(java.lang.Class, com.restfb.MultiqueryParameter, com.restfb.Parameter...)">LegacyFacebookClient.executeMultiquery(Class, MultiqueryParameter, Parameter...)</a> family of methods
			to easily perform multiquery operations with a minimum of configuration.
		</p>			
		
		<p>
			To use the multiquery support, simply create a map of named queries and create a class to hold the results. Here's an example:
		</p>
		
		<pre class="prettyprint">
LegacyFacebookClient facebookClient = new DefaultLegacyFacebookClient(MY_ACCESS_TOKEN);

String friendsQuery =
  "SELECT name, pic_big FROM user " +
  "WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=12345)";

String groupsQuery =
  "SELECT gid, name FROM group WHERE gid IN " +
  "(SELECT gid FROM group_member WHERE uid=12345)";

// The key names specified here map to field names in the result object

Map&lt;String, String&gt; queries = new HashMap&lt;String, String&gt;();
queries.put("friends", friendsQuery);
queries.put("groups", groupsQuery);

// You can send along additional parameters if you'd like, too

Results results =
  facebookClient.executeMultiquery(Results.class, MultiqueryParameter.with(queries));</pre>
		
		<p>
			Here's the result class and its supporting classes.  By default, results are mapped to <code>@Facebook</code>-annotated fields by the
			logical query name specified in the map. You may override this behavior by explicitly specifying the value as shown below on the <code>users</code> field. 
		</p>
		
		<pre class="prettyprint">
class Results {
  @Facebook("friends")
  List&lt;User&gt; users;

  @Facebook
  List&lt;Group&gt; groups;
}

// The multiquery support uses the same recursive mapping as the other parts of RestFB.
// It's not shown in this example, but you can create arbitrarily complex object graphs
// of @Facebook-annotated fields to handle complex query results.

class Group {
  @Facebook(value = "gid")
  Long id;

  @Facebook
  String name;
}

class User {
  @Facebook
  String name;

  @Facebook("pic_big")
  String pictureUrl;
}</pre>		
		
		<div class="spacer"></div>		
		
		<h2>Making a stream.publish Call with Complex Attachments (Since 1.4)</h2>

		<p>
			The <a href="http://wiki.developers.facebook.com/index.php/Stream.publish">stream.publish</a> API call can accept
			<code>attachment</code> and <code>privacy</code> (JSON objects) as well as <code>action_links</code> (JSON array) as parameters.
			The 1.4 release of RestFB supports mapping of Java types to JSON to simplify this use case - you no longer have to
			manually create a JSON string, as the framework will take care of that for you for <code>List</code>s, <code>Map</code>s,
			and your own Javabean types that have fields annotated with the <code>@Facebook</code> annotation.			
		</p>					
		
		<pre class="prettyprint">
LegacyFacebookClient facebookClient = new DefaultLegacyFacebookClient(MY_ACCESS_TOKEN);

ActionLink category = new ActionLink();
category.href = "http://bit.ly/KYbaN";
category.text = "humor";

Properties properties = new Properties();
properties.category = category;
properties.ratings = "5 stars";

Medium medium = new Medium();
medium.href = "http://bit.ly/187gO1";
medium.src = "http://bit.ly/GaTlC";
medium.type = "image";

Attachment attachment = new Attachment();
attachment.name = "i'm bursting with joy";
attachment.href = "http://bit.ly/187gO1";
attachment.caption = "{*actor*} rated the lolcat 5 stars";
attachment.description = "a funny looking cat";
attachment.properties = properties;
attachment.media = Collections.singletonList(medium);

// Send the request to Facebook.
// We specify the session key to use to make the call, the fact that we're
// expecting a String response, and the attachment (defined above).

String postId = facebookClient.execute("stream.publish", String.class,
  Parameter.with("attachment", attachment));</pre>
		
		<p>
			Here are the supporting classes.  You may <a href="LegacyStreamPublishExample.java">download the full example</a> and run it locally.
			Note that you don't have to write your own classes - you can just as easily populate <code>Map</code>s instead
			for a less strongly-typed solution.
		</p>			
		
		<pre class="prettyprint">
class ActionLink {
  @Facebook
  String text;

  @Facebook
  String href;
}

class Medium {
  @Facebook
  String type;

  @Facebook
  String src;

  @Facebook
  String href;
}

class Properties {
  @Facebook
  ActionLink category;

  @Facebook
  String ratings;
}

class Attachment {
  @Facebook
  String name;

  @Facebook
  String href;

  @Facebook
  String caption;

  @Facebook
  String description;

  @Facebook
  Properties properties;

  @Facebook
  List&lt;Medium&gt; media;
}</pre>
		
		<div class="spacer"></div>				
		
		<h2>Running The Examples</h2>
		
		<p>
			RestFB comes with a few example Java source files that you can run and tweak yourself.  Don't forget to put<br/><code>-Daccess_token=MY_ACCESS_TOKEN</code> in quotes!</code>
		</p>
		
<pre>$ cd source/examples
$ ant run-legacy-examples "-Daccess_token=MY_ACCESS_TOKEN"</pre>		
		
		<div class="spacer"></div>				
		
		<h2>JSON Mapping Rules</h2>

		<p>
			Using <code><a href="javadoc/com/restfb/DefaultJsonMapper.html">DefaultJsonMapper</a></code>,
			RestFB is able to recursively map JSON fields annotated with <code>@Facebook</code> to the following Java types out of the box:
		</p>		
		
		<ul>
			<li><code>String</code></li>
			<li><code>Integer</code></li>
			<li><code>Boolean</code></li>
			<li><code>Long</code></li>
			<li><code>Double</code></li>
			<li><code>Float</code></li>
			<li><code>BigInteger</code></li>
			<li><code>BigDecimal</code></li>
			<li>
				Your own JavaBean-compliant classes
				<br/>
				<span class="footnote">
					Don't forget to provide a public default constructor!
				</span>
			</li>
			<li>
				<code>List</code>s of any of the above types		
			</li>
		</ul>
		
		<p>
			For example:	
		</p>
			
		<pre class="prettyprint">
public class MyClass {
  @Facebook
  String name;

  @Facebook
  BigDecimal value;

  @Facebook
  List&lt;Integer&gt; numbers;
}</pre>			
		
		<p>
			As of RestFB 1.4, Java to JSON mapping is supported by default <code><a href="javadoc/com/restfb/JsonMapper.html#toJson(java.lang.Object)">JsonMapper.toJson(Object object)</a></code>.
			You may recursively convert primitive wrapper types as specified above, <code>List</code>s, <code>Map</code>s with <code>String</code> keys, and your own Javabean types
			by applying the <code>@Facebook</code> annotation to any fields you'd like to include in the conversion.
		</p>
		
		<p>
			As-is, <code>DefaultJsonMapper</code> should meet the needs of the vast majority of users.
			If it doesn't support a feature you need, you can easily subclass it or write your own implementation of <code><a href="javadoc/com/restfb/JsonMapper.html">JsonMapper</a></code> instead.
		</p>
			
		<div class="spacer"></div>		
		
		<h2>Error Handling</h2>

		<p>					
			All <code><a href="javadoc/com/restfb/LegacyFacebookClient.html">LegacyFacebookClient</a></code> methods throw the abstract <code><a href="javadoc/com/restfb/FacebookException.html">FacebookException</a></code>.																	
		</p>
		
		<p>
			These are the <code>FacebookException</code> subclasses that you may catch:
		</p>
		
		<ul id="exceptions-list">
			<li>
				<code><a href="javadoc/com/restfb/FacebookJsonMappingException.html">FacebookJsonMappingException</a></code>
				<br/>
				<span class="footnote">					
					Thrown when an error occurs when attempting to map Facebook API response JSON to a Java object.
					It usually indicates that you've used the <code>@Facebook</code> annotation on a field with an unsupported type or
					the Facebook API JSON doesn't map correctly to the fields you've annotated (e.g. attempting to map a JSON string to a Java <code>BigDecimal</code>
					or a JSON object to a Java <code>List</code>).
					
					<div class="spacer"></div>
					
					You generally should not explicitly catch this exception in your code, as it usually signifies programmer
					error in setting up <code>@Facebook</code> annotations.  One valid use for catching this exception,
					however, is to detect when Facebook changes what an API call returns on their end, which would break your live code.
					It may be useful to catch this exception and then send a notification to you or your ops team to notify them
					that your application needs to be updated.
				</span>
			</li>
			<li>
				<code><a href="javadoc/com/restfb/FacebookNetworkException.html">FacebookNetworkException</a></code>
				<br/>
				<span class="footnote">
					Thrown when a failure occurs at the network level.  This can happen if your machine
					doesn't have a network connection or the Facebook API endpoint returns a non HTTP <code>OK</code> (200) status code.
					If there's an HTTP status code available, it's included in the exception so you may take custom actions
					depending on what type of error occurred.
				</span>				
			</li>
			<li>
				<code><a href="javadoc/com/restfb/FacebookResponseStatusException.html">FacebookResponseStatusException</a></code>
				<br/>
				<span class="footnote">
					Thrown when a request is made to Facebook and an HTTP <code>OK</code> (200) response is received, but
					the returned JSON signifies an error condition.
					
					<div class="spacer"></div>
					
					For example, below is the list of errors the Facebook API may return for the <a href="http://wiki.developers.facebook.com/index.php/Stream.removeLike">Stream.removeLike</a> call:
					
					<div class="spacer"></div>					
					<div class="spacer"></div>
					
					<table id="error-table" cellpadding="4">
					<tbody><tr><td><b>Code</b></td><td><b>Description</b></td>
					</tr><tr valign="top"><th style="font-weight: bold;">100</th><td>  Invalid parameter.  </td><td> 
					</td></tr><tr valign="top"><th style="font-weight: bold;">102</th><td>  Session key invalid or no longer valid (if it's a desktop application and the session is missing).  </td><td>
					</td></tr><tr valign="top"><th style="font-weight: bold;">200</th><td>  Permissions error. The application does not have permission to perform this action.  </td><td>
					</td></tr><tr valign="top"><th style="font-weight: bold;">210</th><td style="padding-bottom: 7px;">  User not visible. The user doesn't have permission to act on that object.  </td><td>
					</td></tr></tbody></table>
					
					<div class="spacer"></div>
					<div class="spacer"></div>

					<code>FacebookResponseStatusException</code> will include both the error code and error message returned by the Facebook API
					so you may take custom actions depending on the type of error that occurred.
				</span>				
			</li>
		</ul>
		
		<p>
			Here's some example code to illustrate the above.  Keep in mind that your code doesn't
			need to handle every single exception the way we're doing here - this is just to demonstrate what's possible.
		</p>
		
		<pre class="prettyprint">
try {
  Integer result =
    facebookClient.execute("Stream.removeLike", sessionKey,
      Integer.class, Parameter.with("post_id", "12345"));  
} catch (FacebookJsonMappingException e) {
  // Looks like this API method didn't really return an Integer
} catch (FacebookNetworkException e) {
  // Looks like an error occurred at the network level
  System.out.println("API returned HTTP status code " + e.getHttpStatusCode());
} catch (FacebookResponseStatusException e) {
  // Facebook API returned a specific error
  if (e.getErrorCode() == 200)
    System.out.println("Permission denied!");
} catch (FacebookException e) {
  // This is the catchall handler for any kind of Facebook exception
}</pre>
		
		<div class="spacer"></div>
		
		<h2>Extensibility and Unit Testing</h2>

		<p>
			In addition to <code><a href="javadoc/com/restfb/DefaultLegacyFacebookClient.html">LegacyFacebookClient</a></code>, RestFB provides default implementations
			for <code><a href="javadoc/com/restfb/DefaultWebRequestor.html">WebRequestor</a></code> and
			<code><a href="javadoc/com/restfb/DefaultJsonMapper.html">JsonMapper</a></code>, two components that
			<code>DefaultFacebookClient</code> depends on to do its work.						
		</p>
		
		<p>
			These dependencies are designed to allow for straightforward subclassing (if you only want to replace a little bit of functionality)
			and simple custom implementations (if you require full control).
		</p>
		
		<p>
			This comes in handy when unit testing - for example, you can write your own <code>WebRequestor</code> implementation
			that simulates a Facebook API endpoint response.  You can drop in custom data designed to exercise your application's
			Facebook integration or simulate error conditions to make sure you're handling them properly.				
		</p>
		
		<p>
			Here's a trivial example which shows one way you might implement this:
		</p>

		<pre class="prettyprint">
LegacyFacebookClient facebookClient =
  new DefaultLegacyFacebookClient(MY_ACCESS_TOKEN,
  
    // A one-off <a href="javadoc/com/restfb/DefaultWebRequestor.html">DefaultWebRequestor</a> for testing that returns a hardcoded JSON
    // list of numbers instead of hitting the Facebook API endpoint URL

    new DefaultWebRequestor() {
      @Override
      public <a href="javadoc/com/restfb/WebRequestor.Response.html">Response</a> <a href="javadoc/com/restfb/WebRequestor.html#executePost(java.lang.String, java.lang.String)">executePost</a>(String url, String parameters) throws IOException {
        return new Response(HttpURLConnection.HTTP_OK, "[123,456,789]");
      }
    }, new DefaultJsonMapper());

// Make an API request using the mocked WebRequestor

List&lt;Integer&gt; numbers = facebookClient.<a href="javadoc/com/restfb/LegacyFacebookClient.html#executeForList(java.lang.String, java.lang.Class, com.restfb.Parameter...)">executeForList</a>("ignored", Integer.class); 

// Make sure we got what we were expecting

assert numbers.size() == 3;
assert numbers.get(1) == 456;</pre>
				
	<div class="spacer"></div>
	<div class="spacer"></div>				
				
	<script type="text/javascript">
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
		document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
	</script>
	<script type="text/javascript">
		try {
			var pageTracker = _gat._getTracker("UA-12795899-1");
			pageTracker._trackPageview();
		} catch(err) {}
	</script>
</body>
</html>